import React, { useEffect, useState } from 'react';
import {
  DialogContentText,
  Box,
  TextField,
  Typography,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Radio,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Button,
  styled,
} from '@mui/material';
import { Info as InfoIcon, ExpandMore as ExpandMoreIcon } from '@mui/icons-material';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { simulateNetwork } from '../../../redux/slices/generalSlice';
import { closeLaunchDialog } from '../../../redux/slices/experimentsSlice';
import { openBackendErrorDialog } from '../../../redux/slices/errorsSlice';
import { LAUNCH_MODAL } from '../../../constants';
import {
  bgLight,
  errorFieldBorder,
  experimentInputColor,
  radius,
  fontColor,
  experimentLabelColor,
  primaryColor,
  primaryColorHover,
} from '../../../theme';
import Loader from '../../general/Loader';
import SimpleDialog from './SimpleDialog';
import { getRunConfiguration, editRunConfiguration } from '../../../api/experiments';

// Styled components for custom styling
const StyledRoot = styled(Box)(({ theme }) => ({
  '& .primary-loader': {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    fontWeight: 500,
    color: fontColor,
    fontSize: '1rem',
    height: '10rem',
  },
  '& .MuiFormControl-root': {
    width: '100%',
    marginBottom: theme.spacing(1),
  },
  '& .MuiOutlinedInput-root': {
    background: experimentInputColor,
  },
  '& .MuiFilledInput-root': {
    borderRadius: radius,
    background: experimentInputColor,
    border: '0.075rem solid transparent',
    '&.Mui-error': {
      borderColor: errorFieldBorder,
      boxShadow: '0 0 0 .15rem rgba(242, 69, 61, 0.2)',
    },
  },
  '& .MuiOutlinedInput-notchedOutline': {
    border: '0 !important',
  },
  '& .MuiFilledInput-underline': {
    '&:after, &:before': {
      display: 'none',
    },
  },
  '& .MuiFormLabel-root': {
    fontWeight: 'normal',
    color: fontColor,
    opacity: 0.54,
    '&.MuiInputLabel-shrink': {
      color: experimentLabelColor,
      opacity: 0.87,
    },
  },
  '& .MuiFormHelperText-contained': {
    marginLeft: 0,
  },
  '& .MuiFormHelperText-root': {
    color: errorFieldBorder,
    fontSize: '0.875rem',
    lineHeight: '100%',
  },
  '& .MuiAccordion-root': {
    background: bgLight,
    borderRadius: radius,
    padding: '1rem 1.25rem',
    margin: '1.25rem 0 !important',
    boxShadow: 'none',
    '&:before': {
      display: 'none',
    },
    '& .MuiAccordionSummary-content': {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      '& p': {
        fontSize: '0.95rem',
        lineHeight: 'normal',
        display: 'flex',
        alignItems: 'center',
        margin: 0,
        color: experimentLabelColor,
        '& svg': {
          marginRight: theme.spacing(1),
        },
      },
      '& span': {
        fontSize: '0.95rem',
        lineHeight: 'normal',
        color: primaryColor,
        cursor: 'pointer',
      },
    },
  },
  '& .custom-radio': {
    display: 'flex',
    '& label': {
      width: 'calc((100% - 1.125rem) / 2)',
      cursor: 'pointer',
      '& .MuiRadio-root': {
        display: 'none',
        '&.Mui-checked + .wrap': {
          borderColor: primaryColor,
          background: 'rgba(235, 81, 122, 0.05)',
          '& p': {
            color: primaryColor,
          },
        },
      },
      '&:not(:last-child)': {
        marginRight: '1.125rem',
      },
      '& .wrap': {
        width: '100%',
        height: '8.75rem',
        borderRadius: '0.25rem',
        border: '.15rem solid transparent',
        background: bgLight,
        display: 'flex',
        alignItems: 'center',
        flexDirection: 'column',
        justifyContent: 'center',
        '& p': {
          fontWeight: 500,
          fontSize: '0.95rem',
          lineHeight: 'normal',
          letterSpacing: '0.01rem',
          margin: 0,
          color: experimentLabelColor,
        },
      },
    },
  },
}));

interface LaunchDialogProps {
  open?: boolean;
  experimentName?: string;
  numberOfTrials?: number;
  onRequestClose?: () => void;
  [key: string]: any;
}

/**
 * LaunchDialog Component
 * Dialog for selecting what to simulate (base model or experiment with all conditions)
 */
const LaunchDialog: React.FC<LaunchDialogProps> = ({
  open = false,
  experimentName = '',
  numberOfTrials = 0,
  onRequestClose,
  ...otherProps
}) => {
  const dispatch = useAppDispatch();
  const [value, setValue] = useState<string>(LAUNCH_MODAL.modelState);
  const [runConfig, setRunConfig] = useState({
    asynchronous: true,
    cores: 1,
    parallel: true,
    resource: 'local',
    type: 'mpi_bulletin',
  });
  const [expandConfiguration, setExpandConfiguration] = useState(false);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (open) {
      getRunConfiguration()
        .then((config) => {
          setRunConfig(config || runConfig);
        })
        .catch(() => {
          dispatch(
            openBackendErrorDialog({
              errorMessage: 'Failed to retrieve configuration',
              errorDetails: '',
            }),
          );
        });
    }
  }, [open]);

  const handleConfigurationUpdate = (e: React.MouseEvent): void => {
    e.stopPropagation();
    setLoading(true);

    editRunConfiguration(runConfig)
      .then(() => {
        setLoading(false);
        setExpandConfiguration(false);
      })
      .catch(() => {
        setLoading(false);
        dispatch(
          openBackendErrorDialog({
            errorMessage: 'Failed to update configuration',
            errorDetails: '',
          }),
        );
      });
  };

  const handleAction = (): void => {
    dispatch(closeLaunchDialog());
    dispatch(simulateNetwork(value === LAUNCH_MODAL.experimentState ? true : undefined));
    if (onRequestClose) {
      onRequestClose();
    }
  };

  const handleClose = (): void => {
    dispatch(closeLaunchDialog());
    if (onRequestClose) {
      onRequestClose();
    }
  };

  // Static images placeholder - actual images should be in static/icons/
  const currentModal = '/static/icons/modelSelected.png';
  const currentModalUnselected = '/static/icons/modelUnselected.png';
  const experimentSelected = '/static/icons/experimentSelected.png';
  const experimentUnselected = '/static/icons/experimentUnselected.png';

  return (
    <SimpleDialog
      actionLabel={LAUNCH_MODAL.actionSimulate}
      open={open}
      title={
        <span>
          {LAUNCH_MODAL.actionSimulate}
          {' '}
          <span style={{ color: primaryColor, marginLeft: '5px' }}>
            {experimentName}
          </span>
        </span>
      }
      onAction={handleAction}
      onClose={handleClose}
      {...otherProps}
    >
      <StyledRoot>
        <DialogContentText>{LAUNCH_MODAL.title}</DialogContentText>
        <Box className="custom-radio">
          <Typography component="label">
            <Radio
              checked={value === LAUNCH_MODAL.modelState}
              onChange={(e) => setValue(e.target.value as string)}
              value={LAUNCH_MODAL.modelState}
              name="radio-button"
            />
            <Box className="wrap">
              <img
                src={value === LAUNCH_MODAL.modelState ? currentModal : currentModalUnselected}
                alt="currentModal"
                style={{ marginBottom: '12px', width: '48px', height: '48px' }}
              />
              <Typography>Base Model</Typography>
            </Box>
          </Typography>
          <Typography component="label">
            <Radio
              checked={value === LAUNCH_MODAL.experimentState}
              onChange={(e) => setValue(e.target.value as string)}
              value={LAUNCH_MODAL.experimentState}
              name="radio-button"
            />
            <Box className="wrap">
              <img
                src={
                  value === LAUNCH_MODAL.experimentState
                    ? experimentSelected
                    : experimentUnselected
                }
                alt="completeExperiment"
                style={{ marginBottom: '12px', width: '48px', height: '48px' }}
              />
              <Typography>
                All Conditions ({numberOfTrials})
              </Typography>
            </Box>
          </Typography>
        </Box>

        <Accordion expanded={expandConfiguration}>
          <AccordionSummary
            aria-label="Expand"
            aria-controls="additional-actions-content"
            id="additional-actions-header"
          >
            <Typography>
              <InfoIcon />
              {`Run Configuration : ${LAUNCH_MODAL.defaultResource}`}
            </Typography>
            <Button
              onClick={
                expandConfiguration
                  ? (e) => handleConfigurationUpdate(e)
                  : () => setExpandConfiguration(true)
              }
              disabled={loading}
            >
              {expandConfiguration ? 'Save' : 'Edit'}
            </Button>
          </AccordionSummary>
          <AccordionDetails>
            {loading ? (
              <Box className="primary-loader">
                <Loader />
                Loading ...
              </Box>
            ) : (
              <>
                <FormControl variant="filled">
                  <InputLabel id="select-filled-label">Resources</InputLabel>
                  <Select
                    labelId="select-filled-label"
                    id="select-filled-filled"
                    value={runConfig.resource || 'local'}
                    onChange={(e) =>
                      setRunConfig({ ...runConfig, resource: e.target.value })
                    }
                  >
                    <MenuItem value="local">{LAUNCH_MODAL.defaultResource}</MenuItem>
                  </Select>
                </FormControl>
                <FormControl variant="filled">
                  <InputLabel id="method">Method</InputLabel>
                  <Select
                    labelId="method"
                    id="method"
                    value={runConfig.type || 'mpi_bulletin'}
                    onChange={(e) =>
                      setRunConfig({ ...runConfig, type: e.target.value })
                    }
                  >
                    <MenuItem value="mpi_bulletin">
                      Default - Master/Worker (1 job per core)
                    </MenuItem>
                  </Select>
                </FormControl>
                <TextField
                  variant="filled"
                  label={`CPU Cores - (${(window as any).cores || 1} available)`}
                  type="number"
                  inputProps={{ min: 1, max: (window as any).cores || 1, step: 1 }}
                  value={runConfig.cores || 1}
                  onChange={(e) =>
                    setRunConfig({
                      ...runConfig,
                      cores: parseInt(e.target.value, 10) || 1,
                    })
                  }
                  fullWidth
                  sx={{
                    '& .MuiFilledInput-root': {
                      '&::before': {
                        display: 'none',
                      },
                    },
                  }}
                />
              </>
            )}
          </AccordionDetails>
        </Accordion>
      </StyledRoot>
    </SimpleDialog>
  );
};

export default LaunchDialog;

